package org.dev.hi.hiui.input

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.drawable.ColorDrawable
import android.text.InputFilter
import android.text.InputType
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import org.dev.hi.hiui.R
import kotlin.math.min

/**
 * Author WenPing
 * CreateTime 2021/5/8.
 * Description:
 */
class InputItemLayout : LinearLayout {

    private lateinit var titleView: TextView

    private lateinit var editText: EditText

    private var bottomLine: Line

    private var topLine: Line

    private var topPaint = Paint(Paint.ANTI_ALIAS_FLAG)

    private var bottomPaint = Paint(Paint.ANTI_ALIAS_FLAG)

    constructor(context: Context) : this(context, null)

    constructor(context: Context, attributeSet: AttributeSet?) :
            this(context, attributeSet, 0)

    constructor(context: Context, attributeSet: AttributeSet?, defStyle: Int) : super(
        context, attributeSet, defStyle
    ) {
        // Set a drawable to be used as a divider between items.
        dividerDrawable = ColorDrawable()

        //设置分割线从布局的开始处
        // Set how dividers should be shown between items in this layout
        showDividers = SHOW_DIVIDER_BEGINNING // Show a divider at the beginning of the group.


        val array = context.obtainStyledAttributes(attributeSet, R.styleable.InputItemLayout)
        // 解析自定义属性
        var title = array.getString(R.styleable.InputItemLayout_title)
        var titleResId = array.getResourceId(R.styleable.InputItemLayout_inputTextAppearance, 0)
        // 解析title
        parseTitleStyle(title, titleResId)

        // 解析右侧输入框属性
        var hint = array.getString(R.styleable.InputItemLayout_hint)
        // 获取引用类型
        val inputResId = array.getResourceId(R.styleable.InputItemLayout_inputTextAppearance, 0)
        // 获取枚举 类型
        val inputType = array.getInteger(R.styleable.InputItemLayout_inputType, 0)
        parseInputStyle(hint, inputResId, inputType)

        // 上下分割线属性
        val topResId = array.getResourceId(R.styleable.InputItemLayout_topLineAppearance, 0)
        val bottomResId = array.getResourceId(R.styleable.InputItemLayout_bottomLineAppearance, 0)
        topLine = parseLineStyle(topResId)
        bottomLine = parseLineStyle(bottomResId)
        // 如果启动 设置Paint对应的颜色、风格、宽度
        if (topLine.enable) {
            topPaint.color = topLine.color
            topPaint.style = Paint.Style.FILL_AND_STROKE
            topPaint.strokeWidth = topLine.height
        }

        if (bottomLine.enable) {
            bottomPaint.color = bottomLine.color
            bottomPaint.style = Paint.Style.FILL_AND_STROKE
            bottomPaint.strokeWidth = bottomLine.height
        }

        //recycle 避免内存泄漏
        array.recycle()

    }

    /**
     * 解析下滑线属性
     */
    private fun parseLineStyle(resId: Int): Line {
        val line = Line()
        val array =
            context.obtainStyledAttributes(resId, R.styleable.lineAppearance)
        // 从解析器中解析line的各种属性
        line.run {
            color = array.getColor(
                R.styleable.lineAppearance_color,
                ContextCompat.getColor(context, R.color.color_d1d2)
            )
            height = array.getDimensionPixelOffset(R.styleable.lineAppearance_height, 0).toFloat()
            leftMargin =
                array.getDimensionPixelOffset(R.styleable.lineAppearance_leftMargin, 0).toFloat()
            rightMargin =
                array.getDimensionPixelOffset(R.styleable.lineAppearance_rightMargin, 0).toFloat()
            enable = array.getBoolean(R.styleable.lineAppearance_enable, false)
        }
        array.recycle()
        return line
    }

    private fun parseInputStyle(hint: String?, inputResId: Int, inputType: Int) {
        val array = context.obtainStyledAttributes(inputResId, R.styleable.inputTextAppearance)
        // hintColor
        val hintColor = array.getColor(
            R.styleable.inputTextAppearance_hintColor,
            ContextCompat.getColor(context, R.color.color_d1d2)
        )
        // inputColor
        val inputColor = array.getColor(
            R.styleable.inputTextAppearance_inputColor,
            ContextCompat.getColor(context, R.color.color_565)
        )

        val textSize = array.getDimensionPixelSize(
            R.styleable.inputTextAppearance_textSize,
            applyUnit(TypedValue.COMPLEX_UNIT_SP, 15f)
        )
        // 默认最长输入长度0
        val maxInputLength = array.getInteger(R.styleable.inputTextAppearance_maxInputLength, 0)

        editText = EditText(context)
        if (maxInputLength > 0) {
            // 设置最多可以输入的字符数
            editText.filters = arrayOf(InputFilter.LengthFilter(maxInputLength))
        }
        editText.run {
            setPadding(0, 0, 0, 0)
            val layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
            layoutParams.weight = 1f
            this.layoutParams = layoutParams

            this.hint = hint
            setHintTextColor(hintColor)
            setTextColor(inputColor)
            gravity = Gravity.LEFT or Gravity.CENTER
            setBackgroundColor(Color.TRANSPARENT)
            setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize.toFloat())
        }
        //when判断，根据枚举的值设置输入框的输入类型
        when (inputType) {
            0 -> {
                editText.inputType = InputType.TYPE_CLASS_TEXT
            }
            1 -> {
                editText.inputType =
                    InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT
            }
            2 -> {
                editText.inputType = InputType.TYPE_CLASS_NUMBER
            }
        }
        addView(editText)
        array.recycle()
    }

    /**
     * inputTextAppearance 作为一个 reference，指向一个属性的集合
     * 需要对该属性集合再进行解析，并且赋予对应的value和顺序性
     */
    private fun parseTitleStyle(title: String?, titleResId: Int) {
        // InputItemLayout 自定义属性里有引用到 inputTextAppearance，在获取 inputTextAppearance属性集合
        val array = context.obtainStyledAttributes(titleResId, R.styleable.titleTextAppearance)
        // titleColor
        val titleColor = array.getColor(
            R.styleable.titleTextAppearance_titleColor,
            resources.getColor(R.color.color_565)
        )
        // titleSize
        val titleSize = array.getDimensionPixelSize(
            R.styleable.titleTextAppearance_titleSize,
            applyUnit(TypedValue.COMPLEX_UNIT_SP, 15f)
        )
        //最小宽度
        val minWidth = array.getDimensionPixelOffset(R.styleable.titleTextAppearance_minWidth, 0)

        //创建一个titleView
        titleView = TextView(context)
        //给titleView设置对应的属性
        titleView.run {
            setTextSize(TypedValue.COMPLEX_UNIT_PX, titleSize.toFloat())
            setTextColor(titleColor)
            layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
            this.minWidth = minWidth
            gravity = Gravity.LEFT or (Gravity.CENTER)
            text = title
        }
        //添加到布局
        addView(titleView)
        array.recycle()
    }


    /**
     * 设置文字尺寸
     */
    private fun applyUnit(applyUint: Int, value: Float): Int {
        return TypedValue.applyDimension(applyUint, value, resources.displayMetrics).toInt()
    }

    /**
     * 创建内部类 线
     * 带有线条的
     * 颜色，高度，左右边距和是否启用等属性
     */
    class Line {
        var color = 0
        var height = 0f
        var leftMargin = 0f
        var rightMargin = 0f
        var enable: Boolean = false
    }


    fun getTitleView(): TextView = titleView

    fun getEditTextView(): EditText = editText

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)

        if (topLine.enable) {
            canvas!!.drawLine(
                topLine.leftMargin,
                0f,
                measuredWidth - topLine.rightMargin,
                0f,
                topPaint
            )
        }
        if (bottomLine.enable) {
            canvas!!.drawLine(
                bottomLine.leftMargin,
                0f,
                measuredWidth - bottomLine.rightMargin,
                0f,
                bottomPaint
            )
        }
        

    }


}